package com.nami.client.network.handler;

import com.nami.basic.enums.message.MsgTypeEnum;
import com.nami.basic.packet.Packet;
import com.nami.basic.packet.message.Message;
import com.nami.client.qos.QosItem;
import com.nami.client.qos.QosReceiver;
import com.nami.client.request.LoginRequest;
import com.nami.client.result.ServerResp;
import com.nami.client.utils.ClientKeyUtil;
import com.nami.client.utils.JsonUtils;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


/**
 * 描述：
 *
 * @Author: lbc
 * @Date: 2023-07-14 15:38
 * @email: 594599620@qq.com
 * @Description: keep coding
 */
@Slf4j
public class NettyClientHandler extends SimpleChannelInboundHandler<Packet> {

    private static final ExecutorService executors = Executors.newScheduledThreadPool(10);

    private LoginRequest loginRequest;


    public NettyClientHandler(LoginRequest loginRequest) {
        this.loginRequest = loginRequest;
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("客户端握手成功，[{}]通道激活. 准备认证！", ctx.channel().remoteAddress());
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
        log.warn("[client] inactive.");
    }


    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        log.error("[client] 通道【{}】即将关闭 error:{}", ctx.channel().remoteAddress(), cause.getMessage());
    }

    @Override
    protected void channelRead0(ChannelHandlerContext context, Packet packet) throws Exception {
        Channel channel = context.channel();
        byte[] body = packet.getBody();
        int cmd = packet.getCmd();
        switch (cmd) {
            case 1001:
                ServerResp serverResp = JsonUtils.parseObject(body, ServerResp.class);
                if (serverResp == null) {
                    log.info("[login-resp] 响应null");
                }
                log.info("[client-login] 登录结果：{},{}", serverResp.isSuccess(), serverResp.getErrMessage());
                break;
            case 1002:
                log.info("[pong] 服务器发送来响应包");
                break;
            case 1003:
                log.info("[c2c] 单聊消息");
                break;
            case 1004:
                break;
            case 1005: //群聊
                ServerResp c2gResp = JsonUtils.parseObject(body, ServerResp.class);
                String data = (String) c2gResp.getData();
                Message message = JsonUtils.parseObject(data, Message.class);

                if (message.getType() == MsgTypeEnum.C2G_SENDER_ACK.getCode()) {
//                    log.info("[resp-c2g] 服务器发回的ack messageId={}", message.getId());
                    return;
                }
                if (message.getType() == MsgTypeEnum.DOWN_MSG_C2G_RECEIVER_.getCode()) {
                    // 不返回收到消息，就要被下线
                    CompletableFuture.runAsync(
                        () -> {
                            QosItem item = new QosItem();
                            item.setMsgId(message.getId());
                            item.setSenderId(loginRequest.getUserId());
                            item.setReceiverId(message.getReceiverId());
                            QosReceiver.getInstance().add(ClientKeyUtil.genClientKey(loginRequest.getUserId(),
                                loginRequest.getDeviceType()), item);
                        }, executors);

//                    log.info("[resp-c2g] 我是其他群友{}，收到消息，返回服务器接收msg成功。 msgId={}", loginRequest.getUserId(), message.getId());
                }
                break;
            case 1900:
                log.info("logout success. userId={}", loginRequest.getUserId());
                break;
            default:
                log.warn("error cmd:{}", cmd);
                break;
        }


    }

}
